import pandas as pd
import model


def getGridPlan(maxValue: float, minValue: float, step: float = 5, startPercent: int = 40, money: int = 1000) -> pd.DataFrame:
    """
    获取网格计划
    :param maxValue: 基金最高价格
    :param minValue: 基金最低价格
    :param step: 网格大小
    :param startPercent: 回撤多少开始网格
    :param money: 单笔金额
    :return: pd.DataFrame[基金价格  回撤比例%  加仓批次     购买金额    数量   卖出价格     收益  收益率%]
    """
    gridList = [model.GridInfo(price=maxValue)]

    cur = maxValue
    while cur > minValue:
        cur = round(cur * (100 - step) / 100, 3)
        if cur < minValue:
            break

        percent = round(100 - cur * 100 / maxValue, 1)
        grid = model.GridInfo(price=cur, percent=percent)
        # 回撤比例超过指定回撤比较再开始计算
        if percent >= startPercent:
            grid.batch = gridList[-1].batch + 1
            cnt, dstMoney = _getCntAndDstMoney(money, cur)
            grid.money = dstMoney
            grid.fundCnt = cnt
            grid.sellPrice = gridList[-1].price
            grid.earning = round(grid.fundCnt * (grid.sellPrice - grid.price), 2)
            grid.earningRate = round(grid.earning / grid.money * 100, 2)
        gridList.append(grid)

    if gridList[-1].price > minValue:
        # 如果最低价格大于最小价格，则计算最小价格
        grid = model.GridInfo(price=minValue)
        grid.percent = round(100 - minValue * 100 / maxValue, 2)
        grid.batch = gridList[-1].batch + 1
        cnt, dstMoney = _getCntAndDstMoney(money, minValue)
        grid.money = dstMoney
        grid.fundCnt = cnt
        grid.sellPrice = gridList[-1].price
        gridList.append(grid)
        grid.earning = round(grid.fundCnt * (grid.sellPrice - grid.price), 2)
        grid.earningRate = round(grid.earning / grid.money * 100, 2)

    dict_list = [grid.to_dict() for grid in gridList]

    return pd.DataFrame(dict_list)

def getGridPlanV2(maxValue: float, minValue: float, step: float = 5, startPercent: int = 40, money: int = 1000) -> pd.DataFrame:
    """
    获取网格计划
    :param maxValue: 基金最高价格
    :param minValue: 基金最低价格
    :param step: 网格大小
    :param startPercent: 回撤多少开始网格
    :param money: 单笔金额
    :return: pd.DataFrame[基金价格  回撤比例%  加仓批次     购买金额    数量   卖出价格     收益  收益率%]
    """
    gridList = [model.GridInfo(price=maxValue)]

    cur = maxValue
    while cur > minValue:
        cur = round(cur * (100 - step) / 100, 3)
        if cur < minValue:
            break

        percent = round(100 - cur * 100 / maxValue, 1)
        grid = model.GridInfo(price=cur, percent=percent)
        # 回撤比例超过指定回撤比较再开始计算
        if percent >= startPercent:
            grid.batch = gridList[-1].batch + 1

        else:
            grid.batch = 0

        cnt, dstMoney = _getCntAndDstMoney(money, cur)
        grid.money = dstMoney
        grid.fundCnt = cnt
        grid.sellPrice = gridList[-1].price
        grid.earning = round(grid.fundCnt * (grid.sellPrice - grid.price), 2)
        grid.earningRate = round(grid.earning / grid.money * 100, 2)
        gridList.append(grid)

    if gridList[-1].price > minValue:
        # 如果最低价格大于最小价格，则计算最小价格
        grid = model.GridInfo(price=minValue)
        grid.percent = round(100 - minValue * 100 / maxValue, 2)
        grid.batch = gridList[-1].batch + 1
        cnt, dstMoney = _getCntAndDstMoney(money, minValue)
        grid.money = dstMoney
        grid.fundCnt = cnt
        grid.sellPrice = gridList[-1].price
        gridList.append(grid)
        grid.earning = round(grid.fundCnt * (grid.sellPrice - grid.price), 2)
        grid.earningRate = round(grid.earning / grid.money * 100, 2)

    dict_list = [grid.to_dict() for grid in gridList]

    return pd.DataFrame(dict_list)


def _getCntAndDstMoney(money: int, price: float) -> (int, float):
    """
    根据金额和当前基金价格计算出需要购买多少个基金，以及需要购买多少金额
    :param money: 总金额
    :param price: 基金价格
    :return: ()
    """
    cnt = int(money / price)
    # 网格只能按整百来
    remainder = cnt % 100
    if remainder >= 50:
        cnt = cnt + 100 - remainder
    elif 0 <= remainder < 50:
        cnt = cnt - remainder
    dstMoney = round(cnt * price, 2)
    return cnt, dstMoney
